package net.borderwars.map;

import net.borderwars.util.DoubleMapOfSets;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * @author Eric
 *         Date: Jul 28, 2003
 *         Time: 9:46:56 PM
 */
public class XYMap extends DoubleMapOfSets {
// -------------------------- OTHER METHODS --------------------------

    public void addMappable (Mappable m) {
        // super.put(new Integer(m.getX()), new Integer(m.getY()), m);
    }

    /**
     * Return the set of Mappables centered at x,y with a radius of r
     *
     * @param x
     * @param y
     * @param r
     * @return
     */
    public Set getInRange (int x, int y, int r) {
        Set items = getInRange (x - r, y - r, x + r, y + r);
        HashSet toRemove = new HashSet ();
        for (Iterator i = items.iterator (); i.hasNext ();) {
            Mappable m = (Mappable) i.next ();
            if (!inRange (x, y, r, m)) {
                toRemove.add (m);
            }
        }
        items.removeAll (toRemove);
        return (items);
    }

    private boolean inRange (int x, int y, int r, Mappable m) {
        Location l = m.getLocation ();
        return (inCircle (x, y, r, l.getX (), l.getY ()));
        //return (false);
    }

    /**
     * Is the coordinate tx, ty within the circle centered at x,y radius r
     *
     * @param x
     * @param y
     * @param r
     * @param tx
     * @param ty
     * @return
     */
    private boolean inCircle (int x, int y, int r, double tx, double ty) {
        long dist = distance (x, y, tx, ty);
        if (dist < r) {
            return (true);
        }
        else {
            return (false);
        }
    }

    private long distance (int x, int y, double xx, double yy) {
        int dx = (int) (x - xx);
        int dy = (int) (y - yy);
        double ddx = Math.pow (dx, 2);
        double ddy = Math.pow (dy, 2);
        long rtn = (long) Math.sqrt (ddx + ddy);
        return (rtn);
    }

    public Set getInRange (int x, int y, int xx, int yy) {
        return (getInRange (new Integer (x), new Integer (y), new Integer (xx), new Integer (yy)));
    }
}
